package com.pinchImage.ces;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MyImageViewActivity extends Activity implements OnTouchListener {
	private static final String TAG = "Touch";
	// These matrices will be used to move and zoom image

	private static final int NONE = 0;
	private static final int DRAG = 1;
	private static final int ZOOM = 2;

	private static final float MIN_ZOOM = 1f;
	private static final float MAX_ZOOM = 5f;

	private Matrix matrix = new Matrix();
	private Matrix savedMatrix = new Matrix();

	private PointF start = new PointF();
	private PointF mid = new PointF();

	private float[] values = new float[9];

	private int mode = NONE;
	private float dx;
	private float dy;
	private float matrixX = 0;
	private float matrixY = 0;
	private float width = 0;
	private float height = 0;
	private float oldDistance = 1f;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ImageView view = (ImageView) findViewById(R.id.imageView);
		view.setOnTouchListener(this);
	}

	/*
	 * public boolean onTouch(View v, MotionEvent event) { ImageView view =
	 * (ImageView) v;
	 * 
	 * // Dump touch event to log dumpEvent(event);
	 * 
	 * // Handle touch events here... switch (event.getAction() &
	 * MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN:
	 * savedMatrix.set(matrix); start.set(event.getX(), event.getY());
	 * Log.d(TAG, "mode=DRAG"); mode = DRAG; break; case
	 * MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG,
	 * "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix);
	 * midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case
	 * MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE;
	 * Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode ==
	 * DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX()
	 * - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float
	 * newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist >
	 * 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist;
	 * matrix.postScale(scale, scale, mid.x, mid.y); } } break; }
	 * 
	 * view.setImageMatrix(matrix); return true; // indicate event was handled }
	 * 
	 * /** Show an event in the LogCat view, for debugging
	 */
	/*
	 * private void dumpEvent(MotionEvent event) { String names[] = { "DOWN",
	 * "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?",
	 * "8?", "9?" }; StringBuilder sb = new StringBuilder(); int action =
	 * event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK;
	 * sb.append("event ACTION_").append(names[actionCode]); if (actionCode ==
	 * MotionEvent.ACTION_POINTER_DOWN || actionCode ==
	 * MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( action >>
	 * MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append("[");
	 * for (int i = 0; i < event.getPointerCount(); i++) {
	 * sb.append("#").append(i);
	 * sb.append("(pid ").append(event.getPointerId(i));
	 * sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int)
	 * event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); }
	 * sb.append("]"); Log.d(TAG, sb.toString()); }
	 * 
	 * /** Determine the space between the first two fingers
	 */
	/*
	 * private float spacing(MotionEvent event) { float x = event.getX(0) -
	 * event.getX(1); float y = event.getY(0) - event.getY(1); return
	 * FloatMath.sqrt(x * x + y * y); }
	 * 
	 * /** Calculate the mid point of the first two fingers
	 */
	/*
	 * private void midPoint(PointF point, MotionEvent event) { float x =
	 * event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1);
	 * point.set(x / 2, y / 2); }
	 */

	public boolean onTouch(View view, MotionEvent event) {
		ImageView imageView = (ImageView) view;

		switch (event.getAction() & MotionEvent.ACTION_MASK) {

		case MotionEvent.ACTION_DOWN:
			savedMatrix.set(matrix);
			start.set(event.getX(), event.getY());
			mode = DRAG;
			break;

		case MotionEvent.ACTION_POINTER_DOWN:
			oldDistance = spacing(event);
			if (oldDistance > 10f) {
				savedMatrix.set(matrix);
				midPoint(mid, event);
				mode = ZOOM;
			}
			break;

		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			mode = NONE;
			break;

		case MotionEvent.ACTION_MOVE:
			if (mode == DRAG) {
				matrix.set(savedMatrix);
				matrix.getValues(values);
				matrixX = values[Matrix.MTRANS_X];
				matrixY = values[Matrix.MTRANS_Y];
				width = values[Matrix.MSCALE_X]
						* imageView.getDrawable().getIntrinsicWidth();
				height = values[Matrix.MSCALE_Y]
						* imageView.getDrawable().getIntrinsicHeight();
				dx = event.getX() - start.x;
				dy = event.getY() - start.y;
				if (matrixY + dy > 0)
					while (matrixY + dy > 0)
						dy--;
				if (matrixX + dx + width < imageView.getWidth())
					while (matrixX + dx + width < imageView.getWidth())
						dx++;
				if (matrixY + dy + height < imageView.getHeight())
					while (matrixY + dy + height < imageView.getHeight())
						dy++;
				if (matrixX + dx > 0)
					while (matrixX + dx > 0)
						dx--;
				matrix.postTranslate(dx, dy);
			} else if (mode == ZOOM) {
				float newDistance = spacing(event);
				if (newDistance > 10f) {
					matrix.set(savedMatrix);
					float scale = newDistance / oldDistance;
					matrix.getValues(values);
					float currentScale = values[Matrix.MSCALE_X];
					if (scale * currentScale > MAX_ZOOM)
						scale = MAX_ZOOM / currentScale;
					else if (scale * currentScale < MIN_ZOOM)
						scale = MIN_ZOOM / currentScale;
					matrix.postScale(scale, scale, mid.x, mid.y);
				}
			}
			break;
		}
		imageView.setImageMatrix(matrix);
		return true;
	}

	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	private void midPoint(PointF point, MotionEvent event) {
		point.set((event.getX(0) + event.getX(1)) / 2,
				(event.getY(0) + event.getY(1)) / 2);
	}

}